﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using SocketControl.EventArgs;
namespace SocketControl
{
    public abstract class BaseSocketControl
    {

        #region 基础属性

        /// <summary>
        /// 本地scoket
        /// </summary>
        public Socket localsocket = null;

        /// <summary>
        /// 远程socket
        /// </summary>
        public BaseSocketControl remotesocket;

        /// <summary>
        /// 本发Socket连接状态
        /// </summary>
        public bool connected
        {
            get
            {
                if (this.localsocket != null)
                {
                    return this.localsocket.Connected;
                }
                return false;
            }
        }

        /// <summary>
        /// 接收缓存
        /// </summary>
        protected byte[] _sendPacket = null;

        /// <summary>
        /// 接收缓存
        /// </summary>
        public static int cache = 64;

        public static int recvcache = 256;

        /// <summary>
        /// 接收包
        /// </summary>
        protected byte[] _recvPacket = null;

        /// <summary>
        /// 接收数据包列表
        /// </summary>
        protected byte[] tmp = null;
        /// <summary>
        /// 同步线程状态(退出时设为false)
        /// </summary>
        public bool exit = true;

        /// <summary>
        /// 长连接
        /// </summary>
        public bool keepconnect = true;
        #endregion

        #region 套接字属性
        public AddressFamily addressfamily = AddressFamily.InterNetwork;
        public ProtocolType protocoltype = ProtocolType.Tcp;
        public SocketType sockettype = SocketType.Stream;
        protected IPEndPoint ipendpoint = null;
        #endregion

        #region 事件定义

        /// <summary>
        /// 收到一个请求事件委托
        /// </summary>
        /// <param name="e"></param>
        public delegate void OnAcceptEvent(EventCompletedArgs e);

        /// <summary>
        /// 收到一个请求事件
        /// </summary>
        public virtual event OnAcceptEvent OnAccept;

        /// <summary>
        /// 接收数据委托
        /// </summary>
        /// <param name="e"></param>
        public delegate void OnRecvCompletedEvent(EventCompletedArgs e);

        /// <summary>
        /// 接受数据完成事件
        /// </summary>
        public virtual event OnRecvCompletedEvent OnRecvCompleted;

        /// <summary>
        /// 发送数据包事件委托
        /// </summary>
        /// <param name="e"></param>
        public delegate void OnSendCompletedEvent(EventCompletedArgs e);

        /// <summary>
        /// 发送数据完成事件
        /// </summary>
        public virtual event OnSendCompletedEvent OnSendCompleted;

        /// <summary>
        /// 错误事件委托
        /// </summary>
        /// <param name="e"></param>
        public delegate void OnErrorEvent(Exception e);

        /// <summary>
        /// 错误事件
        /// </summary>
        public virtual event OnErrorEvent OnError;

        #endregion

        public BaseSocketControl()
        {
            try
            {
                localsocket = new Socket(this.addressfamily, this.sockettype, this.protocoltype);
            }
            catch (Exception e)
            {
                if (this.OnError != null)
                {
                    OnError(e);
                }
                throw new NotImplementedException(e.Message, e);
            }
        }

        public BaseSocketControl(Socket s)
        {
            localsocket = s;
        }

        /// <summary>
        /// 连接
        /// </summary>
        public virtual void connect(string ip, int port)
        {
            try
            {
                if (localsocket == null)
                {
                    localsocket = new Socket(this.addressfamily, this.sockettype, this.protocoltype);
                }
                ipendpoint = new IPEndPoint(IPAddress.Parse(ip), port);
                localsocket.Connect(ipendpoint);
            }
            catch (Exception e)
            {
                if (this.OnError != null)
                {
                    OnError(e);
                }
                throw new NotImplementedException(e.Message, e);
            }
        }

        /// <summary>
        /// 绑定
        /// </summary>
        public virtual void bind(string ip, int port)
        {
            try
            {
                if (localsocket == null)
                {
                    localsocket = new Socket(this.addressfamily, this.sockettype, this.protocoltype);
                }
                ipendpoint = new IPEndPoint(IPAddress.Parse(ip), port);
                localsocket.Bind(ipendpoint);
            }
            catch (Exception e)
            {
                if (this.OnError != null)
                {
                    OnError(e);
                }
                throw new NotImplementedException(e.Message, e);
            }
        }

        /// <summary>
        /// 监听
        /// </summary>
        public virtual void listen(int backlog = 100)
        {
            try
            {
                this.localsocket.Listen(backlog);
            }
            catch (Exception e)
            {
                if (this.OnError != null)
                {
                    OnError(e);
                }
                throw new NotImplementedException(e.Message, e);
            }
        }

        /// <summary>
        /// 接收连接
        /// </summary>
        public virtual void accept()
        {

        }

        /// <summary>
        /// 发送包
        /// </summary>
        public virtual void send(byte[] buffer, bool depacket = true)
        {

        }

        /// <summary>
        /// 接收包
        /// </summary>
        public virtual void recv()
        {

        }

        /// <summary>
        /// 关闭套接字
        /// </summary>
        public virtual void close()
        {
            this._recvPacket = null;
            this._sendPacket = null;
            this.exit = false;
            this.ipendpoint = null;
            if (this.localsocket != null)
            {
                this.localsocket.Shutdown(SocketShutdown.Both);
                this.localsocket.Close();
                this.localsocket.Dispose();
                this.localsocket = null;
            }
            if (this.remotesocket != null)
            {
                this.remotesocket.exit = false;
            }
        }
    }
}
